Field-like events are events that do
not have explicit add
and remove
accessors.
public event EventHandler MyEvent; // No add and remove accessors
The compiler generates a private
delegate
field to back the event, as well as generating the implicit add
and remove
accessors.
When a virtual
field-like event
is overridden by another field-like event
, the behavior of the C# compiler
is to generate a new private
delegate
field in the derived class, separate from the parent’s field. This results in multiple
and separate events being created, which is rarely what’s actually intended.
Noncompliant code example
abstract class Car
{
public virtual event EventHandler OnRefuel; // Noncompliant
public void Refuel()
{
// This OnRefuel will always be null
if (OnRefuel != null)
{
OnRefuel(this, EventArgs.Empty);
}
}
}
class R2 : Car
{
public override event EventHandler OnRefuel;
}
class Program
{
static void Main(string[] args)
{
var r2 = new R2();
r2.OnRefuel += (o, a) =>
{
Console.WriteLine("This event will be called");
};
r2.Refuel();
}
}
Compliant solution
To prevent this, remove the virtual
designation from the parent class event.
abstract class Car
{
public event EventHandler OnRefuel; // Compliant
public void Refuel()
{
if (OnRefuel != null)
{
OnRefuel(this, EventArgs.Empty);
}
}
}
class R2 : Car
{
}
class Program
{
static void Main(string[] args)
{
var r2 = new R2();
r2.OnRefuel += (o, a) =>
{
Console.WriteLine("This event will be called");
};
r2.Refuel();
}
}